/**
 * MailServer es reponsable de comunicarse con los objetos MailCliente para
 * proporcionarle los servicios necesarios.
 * 
 */
package server;

import listas.HandlerList;
import client.MailClient;
import java.io.Serializable;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import mensaje.Message;

/**
 *Clase servidor principal que se encarga 
 * del envio recepcion y validacion de mensajes
 * entre clientes registrados del servidor.
 * @author Lab-214-21
 * @version 1.1.1
 */
public class MailServer implements Serializable{
    private FileServer server;
    private HandlerList listas;
 
    /**
     * Contructor de la clase, recibe como parametro el nombre con el cual
     * se identificara al servidor posteriormente.
     * @param nombre 
     */
    public MailServer(String nombre) {     
        server = new FileServer(nombre);
        listas = new HandlerList();
    }
    
    /**
     * Método que obtiene el número de mensajes esperando para el usuario que 
     * los solicita.
     * @param name String
     * @return int Un entero que es el resultado
     */
    public int getMessagesWaiting(String name){
        int cont = 0;
        for (int i = 0; i < listas.cantidadMensajes(); i++) {
            Message mensaje  = listas.obtenerMensajePosicion(i);
            cont = validarUsuarioNombre(mensaje,name,cont);
        }
        return cont;
    }
    
    /**
     * Metodo que encapsula la validacion del nombre de un usuario,
     * para usarse dentro del metodo getMessageWaiting
     * @param mensaje
     * @param nombreCliente
     * @param cont
     * @return 
     */
    private int validarUsuarioNombre(Message mensaje, String nombreCliente,int cont){
        if (mensaje.compararDestino(nombreCliente)) {
            if (mensaje.obtenerEstadoMensaje().equals("En espera")) {
                cont ++;
            }
            return cont;
        }     
        return cont;
    }
    
    /**
     * Método que devuelve el siguiente mensaje para el usuario que lo solicita.
     * @param name String
     * @return Message Un objeto Message con el mensaje del usuario
     */
    public Message getNextMessage(String name){ 
        Message mensajeAutenticado = null;
        for (int i = 0; i < listas.cantidadMensajes(); i++) {
            Message mensaje = listas.obtenerMensajePosicion(i); 
            mensajeAutenticado = validarMensajeDestinatario(mensaje, name, mensajeAutenticado,i);           
        }        
        return mensajeAutenticado;
    }
    
    /**
     * Metodo que encapsula la validacion del mensaje destinatario,
     * para usarse dentro del metodo getNextMessage
     * @param mensaje
     * @param nombreComparar
     * @param mensajeAutenticado
     * @param posicion
     * @return 
     */
    public Message validarMensajeDestinatario(Message mensaje,String nombreComparar, 
            Message mensajeAutenticado,int posicion){
        if (mensajeAutenticado != null) {
            return mensajeAutenticado;
        }
        String estadoMensaje = mensaje.obtenerEstadoMensaje();
        if ((mensaje.compararDestino(nombreComparar))&& (estadoMensaje.equals("En espera"))) {
            mensaje.cambiarEstadoMensaje(2);
            return mensaje;
        }
        return null;
    }
    
    /**
     * Método que lista todos los mensajes pendientes que tiene el servidor
     * de correo.
     */
    public void listarMensajes(){
        for (int i = 0; i < listas.cantidadMensajes(); i++) {
            Message mensajeObtenido = listas.obtenerMensajePosicion(i);
            System.out.println(mensajeObtenido.toString());
        }
    }
    
    /**
     * Metodo que recibe los mensajes a enviar. y los almacena en un LinkedList de
     * Mensages por enviar.
     * @param message 
     */
    public void post(Message message){        //hecho
        listas.agregarMensaje(message);
    }   

    /**
     * agrega un cliente a la lista de cliente activos del servidor
     * @param client 
     */
    public void addMailClient(MailClient client){
        listas.agregarCliente(client);
    }
    
    /**
     * Registra un nuevo usuario en el servidor.
     * @param nameUser 
     */
    public void registrarUsuario(ServerUser nameUser){
        server.agregarUsuario(nameUser);
    }
    
    /**
     * elimina un usuario registrado del servidor actual.
     * @param nameUser 
     */
    public void eliminarUsuario(String nameUser){
        server.eliminarUsuario(nameUser);
    }
    
    /**
     * Retorna true o false si el nombre de usuario mandado por parametros
     * se encuentra registrado en este servidor.
     * @param nameUser El nombre del usuario a validar.
     * @return 
     */
    public boolean usuarioValido(String nameUser){
        return server.existeUsuario(nameUser);
    }
    
    /**
     * Obtiene todos los mensajes que corresponden
     * al usuario userName, devolviendo una lista 
     * de todos los mensajes.
     * @param userName
     * @return 
     */
    public ArrayList<Message> obtenerMensajesUsuario(String userName){
        return listas.obtenerMensajes(userName);
    }
    
    /**
     * Elimina el mensajeEliminar del servidor.
     * @param mensajeEliminar 
     */
    public void eliminarMensaje(Message mensajeEliminar){
        listas.eliminarMensaje(mensajeEliminar);
    }   
    
    /**
     * Devuelve la cantidad de usuarios registrados en el servidor.
     * @return 
     */
    public int cantidadUsuarioRegistrados(){
        return server.cantidadUsuarios();
    }
    
    /**
     * Obtiene una lista de todos los usuarios
     * registrados en el servidor.
     * @return 
     */
    public ArrayList<String> obtenerUsuariosRegistrados(){
        return server.obtenerUsuariosRegistrados();
    }
    
    /**
     * Obtiene la foto con la que fue registrado el usuario.
     * @param nameUser nombre del usuario del que se obtendra su foto.
     * @return 
     */
    public ImageIcon obtenerFotoUsuario(String nameUser){
        return server.obtenerFotoUsuario(nameUser);
    }
    
    /**
     * Retorna la representacion en cadena del servidor.
     * @return 
     */
    @Override
    public String toString(){
        return server.toString();
    }
}
